package svc

import (
	"fmt"
	"gitee.com/gopher2011/casdoor/internal/config"
	"github.com/kotlin2018/mbt"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/syncx"
	"gorm.io/driver/mysql"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/schema"
	"log"
	"strconv"
)

var Svc *ServiceContext

type ServiceContext struct {
	Config config.Config
	DB     *gorm.DB
	Cache  cache.Cache
}

func NewServiceContext(c config.Config) {
	var (
		conn *gorm.DB
		dsn  string
		err  error
	)
	gormC := &gorm.Config{
		SkipDefaultTransaction: false, //启用事务
		NamingStrategy: schema.NamingStrategy{
			TablePrefix:   "",   //表前缀
			SingularTable: true, //使用单数表名
		},
		DryRun:                                   false,                               //禁止SQL空跑
		DisableForeignKeyConstraintWhenMigrating: true,                                //创建逻辑外键
		Logger:                                   logger.Default.LogMode(logger.Info), //输出 SQL语句
	}
	switch c.Database.DriverName {
	case "mysql":
		dsn = c.Database.User + ":" + c.Database.Password + "@tcp(" + c.Database.Host + ":" + strconv.Itoa(c.Database.Port) + ")/" + c.Database.DBName + "?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai"
		conn, err = gorm.Open(mysql.New(mysql.Config{
			DSN:               dsn,
			DefaultStringSize: 171, //数据库varchar类型的默认值
		}), gormC)
	case "postgres":
		dsn = fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable TimeZone=Asia/Shanghai", c.Database.Host, c.Database.Port, c.Database.User, c.Database.Password, c.Database.DBName)
		conn, err = gorm.Open(postgres.Open(dsn), gormC)
	}
	if err != nil {
		log.Fatalln("connect database err", err)
	}
	mbt.New(&mbt.Database{
		Pkg:        "./xml",
		DriverName: c.Database.DriverName,
		DSN:        dsn,
		Logger: &mbt.Logger{
			PrintSql: true,
			PrintXml: false,
			Path:     "./log.log",
		},
	}).Run()
	Svc = &ServiceContext{
		Config: c,
		DB:     conn,
		Cache:  cache.New(c.CacheRedis, syncx.NewSingleFlight(), cache.NewStat(""), nil),
	}
}

func (it *ServiceContext) AutoMigrate() {
	it.DB.AutoMigrate()
}
